/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.core.index;

import com.inspur.edp.lcm.metadata.api.entity.MetadataPackage;
import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenPackageRefs;
import com.inspur.edp.lcm.metadata.core.entity.MdProjDependencySource;
import com.inspur.edp.lcm.metadata.core.entity.MdProjectDependencyNode;
import com.inspur.edp.lcm.metadata.devcommon.ManagerUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;

/**
 * maven依赖元数据工程缓存
 *
 * @author sunhongfei01
 * @date modify by 2021-8-2
 */
@Slf4j
class MetadataPackageIndexServiceForMaven extends MetadataPackageIndexService {

    private static MetadataPackageIndexServiceForMaven instance;

    public static MetadataPackageIndexServiceForMaven getInstance() {
        if (instance == null) {
            instance = new MetadataPackageIndexServiceForMaven();
        }
        return instance;
    }

    /**
     * 获取Maven依赖引用节点
     *
     * @param mavenRef maven引用信息
     * @return maven依赖引用节点
     */
    public MdProjectDependencyNode getMetadataDependencyNode(MavenPackageRefs mavenRef) {
        String mavenPath = ManagerUtils.getMavenStoragePath();


        String indexKey = mavenRef.getGroupId() + "-" + mavenRef.getArtifactId() + "-" + mavenRef.getVersion();
        MdProjectDependencyNode cacheNode = getNodeFromCache(mavenPath, indexKey);

        MdProjectDependencyNode fileNode = getDependencyNodeInfoFromDir(mavenPath, indexKey, true);

        if (fileNode == null) {
            removeNodeFromCache(mavenPath, indexKey);
            return null;
        }

        // 若文件节点与缓存节点不一致
        // 根据文件构造元数据包对象,并获取其元数据编码列表 以及元数据包的依赖信息
        if (!fileNode.equals(cacheNode)) {
            cacheNode = fileNode;
            // 记录版本信息
            cacheNode.setSourceVersion(mavenRef.getVersion());

            // 记录来源
            cacheNode.setSourceName(MdProjDependencySource.Maven);

            // 将缓存中的节点填充 其依赖节点以及工程内元数据编码列表 内容
            String packageLocation = fileServiceImp.getDirectoryName(cacheNode.getLocation());
            MetadataPackage metadataPackageInfo = metadataManager.getMetadataPackageInfo(cacheNode.getMetadataPackageName(), packageLocation);

            // 获取元数据包中的metadataIds
            List<String> idsInMdPkg = getMetadataIdsInMdPkg(metadataPackageInfo);
            cacheNode.setMetadataIds(idsInMdPkg);

            // 补充maven引用
            List<MavenPackageRefs> mavenRefsInPom = getMavenRefsInPom(cacheNode);
            cacheNode.setMavenRefs(mavenRefsInPom);
            // 补充元数据包引用
            Set<String> metadataRefsInMdPkg = getMetadataRefsInMdPkg(metadataPackageInfo);
            cacheNode.setMetadataPackageRefs(metadataRefsInMdPkg);

            // 补充数据库数据包引用
            Set<String> mdpkgRefsInMdPkg = getMdpkgRefsInMdPkg(metadataPackageInfo);
            cacheNode.setMdpkgRefs(mdpkgRefsInMdPkg);

            // 补充IDP元数据引用
            Set<String> idpMetadataIds = getIdpMdIdsInMdPkg(metadataPackageInfo);
            cacheNode.setIdpMetadataIds(idpMetadataIds);

            // 将构造节点写入缓存
            saveNodeToCache(mavenPath, indexKey, cacheNode);
        }
        return cacheNode;
    }

    /**
     * 获取pom中记录的当前元数据包依赖maven引用列表
     *
     * @param cacheNode 当前元数据包节点
     * @return 当前元数据包依赖maven引用列表
     */
    private List<MavenPackageRefs> getMavenRefsInPom(MdProjectDependencyNode cacheNode) {
        List<MavenPackageRefs> mavenPackageRefs = new ArrayList<>();
        // 添加maven依赖
        String depFileLocation = cacheNode.getDepFileLocation();
        if (depFileLocation != null) {
            Model model = getModel(depFileLocation);
            if (model != null && model.getDependencies() != null) {
                for (Dependency dependency : model.getDependencies()) {
                    MavenPackageRefs ref = new MavenPackageRefs();
                    ref.setGroupId(dependency.getGroupId());
                    ref.setArtifactId(dependency.getArtifactId());
                    ref.setVersion(dependency.getVersion());
                    mavenPackageRefs.add(ref);
                }
            }
        }
        return mavenPackageRefs;
    }
}
